package com.heima.wemedia.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateTime;
import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.common.utils.CollectionUtils;
import com.alibaba.nacos.common.utils.StringUtils;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.heima.model.common.dtos.PageResponseResult;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.dtos.WmNewsPageReqDto;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.kafka.message.KafkaMessageConstants;
import com.heima.model.wemedia.entity.WmMaterial;
import com.heima.model.wemedia.entity.WmNews;
import com.heima.model.wmNewsDto.WmNewsDto;
import com.heima.utils.common.WmThreadLocalUtil;
import com.heima.wemedia.dao.WmMaterialDao;
import com.heima.wemedia.dao.WmNewsDao;
import com.heima.wemedia.dao.WmNewsMaterialDao;
import com.heima.wemedia.service.WmNewsMaterialService;
import com.heima.wemedia.service.WmNewsService;

import com.itheima.wemedia.service.WmNewsAutoScanService;
import org.springframework.beans.BeanUtils;

import org.springframework.kafka.core.KafkaOperations;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;

import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
 * 自媒体文章表(WmNews)表服务实现类
 *
 * @author makejava
 * @since 2022-04-12 16:02:40
 */
@Service("wmNewsService")
public class WmNewsServiceImpl implements WmNewsService {
    @Resource
    private WmNewsDao wmNewsDao;
    @Resource
    private WmNewsMaterialDao wmNewsMaterialDao;
    @Resource
    private WmMaterialDao wmMaterialDao;
    @Resource
    private KafkaTemplate kafkaTemplate;




    @Override
    public WmNews queryById(Long id) {
        return wmNewsDao.queryById(id);
    }

    @Override
    public org.springframework.data.domain.Page<WmNews> queryByPage(WmNews wmNews, PageRequest pageRequest) {
        return null;
    }

    @Override
    public WmNews insert(WmNews wmNews) {
        return null;
    }

    @Override
    public WmNews update(WmNews wmNews) {
        return null;
    }

    @Override
    public ResponseResult deleteById(Long id) {
        //先根据id查询数据 如果为空说明不存在这个文章
        WmNews wmNews = wmNewsDao.queryById(id);
        if (wmNews == null) {
            return  ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST);
        }
        //判断文章是否存在 发布情况
        if (wmNews.getStatus()==9) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NO_OPERATOR_AUTH,"已经发布的文章不可以删除");
        }
        //直接删除
        wmNewsDao.deleteById(id);
        //删除文章数据关联表
        wmNewsMaterialDao.deleteByNewsId(wmNews.getId());
        return ResponseResult.okResult("删除成功");
    }
    /**
     * 自媒体文章列表
     */
    @Override
    public ResponseResult list(WmNewsPageReqDto dto) {
        if (dto==null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        dto.checkParam();
        //获取userId

        Map<String, Object> map = BeanUtil.beanToMap(dto);
        map.put("userId",WmThreadLocalUtil.getId().getUserId());

        //进行分页查询
        PageHelper.startPage(dto.getPage(), dto.getSize());
        Page<WmNews> page= wmNewsDao.queryByMap(map);

        PageResponseResult result = new PageResponseResult(dto.getPage(), dto.getSize(), (int)page.getTotal());
        result.setData(page.getResult());
        return result;
    }
    /**
     * 文章发布上传提交
     */
    @Override
    public ResponseResult submit(WmNewsDto dto) {
        //判断用户上传的 标题和内容是否为空 空直接返回
        if (dto.getContent()==null&&dto.getTitle()==null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        //对象拷贝
        WmNews wmNews = new WmNews();
        BeanUtils.copyProperties(dto, wmNews);
        //获取文章内容里面的图片 并判断个数  如果布局类型是自动的 就需要去判断文章内容图片个数
            //将文章内容转 map集合进行流化
        List<Map> maps = JSON.parseArray(dto.getContent(), Map.class);
        List<String> contentImages = maps.stream().filter(map ->
                "image".equals(map.get("type"))
        ).map(map -> map.get("value").toString()).collect(Collectors.toList());
        //获取封面图片对象 如果是自动布局就根据内容图片数量进行赋值
        List<String> images = dto.getImages();
        //进行判断   //判断封面图片类型是什么 布局类型;0 : 无图 1 :单图 3:多图  -1自动 获取封面内容
        if(dto.getType()==-1){
            if (contentImages.size()>=3){
                images=contentImages.stream().limit(3).collect(Collectors.toList());
                wmNews.setType((short) 3);
            }else if (contentImages.size()>0) {
                images=contentImages.stream().limit(1).collect(Collectors.toList());
                wmNews.setType((short) 1);
            }else {
                images= Collections.EMPTY_LIST;
                wmNews.setType((short) 0);
            }
        }
        //因为images 类型不一致需要获取出来转成字符格式 存进去
       if (CollectionUtils.isNotEmpty(images)){
           wmNews.setImages(StringUtils.join(images,","));
       }
        //将数据封装进实体 添加到数据库  调用方法 保存新增修改
        saveOrUpdate(wmNews);
        //保存文章和内容素材的引用关系
        saveContentImageRelation(wmNews, contentImages);
        //保存文章和封面素材的引用关系
        saveCoverImageRelation(wmNews, images);


        //自定义 铭感词汇 检查
        //在此保存之前判断用户是提交 还是保存草稿 提交就需要进行审核阶段 状态为1 就需要审核
        if(wmNews.getStatus()==1){
            kafkaTemplate.send(KafkaMessageConstants.WM_NEWS_AUTO_SCAN_TOPIC,Long.toString(wmNews.getId()));
        }
        //返回添加成功
        return ResponseResult.okResult("发布成功");
    }



    //保存文章和封面素材的引用关系
    private void saveCoverImageRelation(WmNews wmNews, List<String> images) {
        //先判断图片是否为空 空就不需要建立表
        if (CollectionUtils.isEmpty(images)) {
            return;
        }
        saveImageRelation(wmNews, images, (short) 1);
    }


    //保存文章和内容素材的引用关系
    private void saveContentImageRelation(WmNews wmNews, List<String> contentImages) {
        //先判断图片是否为空 空就不需要建立表
        if (CollectionUtils.isEmpty(contentImages)) {
            return;
        }
        saveImageRelation(wmNews, contentImages, (short) 0);
    }
    //保存文章内容,封面数据
    private void saveImageRelation(WmNews wmNews, List<String> contentImages, short i) {
        //先判断内容是不是草稿 状态为0就是草稿不需要建立链接\
        if (wmNews.getStatus()==0) {
            return;
        }
        //获取素材的id 先去重 用户可能存储相同的图片
       contentImages = contentImages.stream().distinct().collect(Collectors.toList());
        //根据路径查询素材
        List<WmMaterial> materialList= wmMaterialDao.queryByUls(contentImages);
        //获取出所有的ids
        List<Long> ids = materialList.stream().map(
                wmMaterial -> wmMaterial.getId()
        ).collect(Collectors.toList());
        //判断素材是否丢失 比较两个size的大小就可以
        if (contentImages.size()>ids.size()) {
            throw new RuntimeException("素材数据丢失");
        }
        //走到这里就可以保存数据到 关联表
        wmNewsMaterialDao.saveImageRelation(wmNews.getId(), ids, i);
    }

    /**
     * 新增 修改 保存操作
     * @param wmNews
     */
    private void saveOrUpdate(WmNews wmNews) {
        //先判断这个是图片是否存在相同的数据
        wmNews.setUserId(WmThreadLocalUtil.getId().getUserId());
        wmNews.setCreatedTime(new Date());
        wmNews.setEnable(1);

        //先查询这个保存这个id的数据是否存在  不存在保存
        if (wmNews.getId()==null) {
            wmNews.setUpdatedTime(new Date());
            wmNewsDao.insert(wmNews);
            return;
        }
        //如果存在就先删除再保存 ---修改
            wmNewsDao.update(wmNews);
        //如果存在 就说明修改操作 需要修改了 要把文章素材关联表删除
        wmNewsMaterialDao.deleteByNewsId(wmNews.getId());
    }
}
